<?php

defined('BASEPATH') or exit('No direct script access allowed');

/**
 * Description of Users
 *
 * @author doufu <442958506@qq.com>
 */
class Notify extends MY_Controller {

	public function __construct() {
		parent::__construct();
		$this->load->config('rest');
		$this->lang->load('code');
	}

	public function wxpay() {
		$this->load->library('wxpay_notify');
		$result = $this->wxpay_notify->Handle(FALSE);

		if ($result && !empty($this->wxpay_notify->data)) {
			//更新订单状态
			$this->load->model('api/Order_model', 'Order');
			$data = array(
				'pay_method' => REST_Controller::PAY_METHOD_WECHAT,
				'status' => REST_Controller::PAY_STATUS_PAYED,
				'pay_time' => time(),
				'ext_order_num' => $this->wxpay_notify->data["transaction_id"],
				'sign_for_code' => rand(1000, 9999),
				'updated_at' => time()
			);
			$where = array(
				'order_num' => $this->wxpay_notify->data['out_trade_no'],
				'status' => REST_Controller::PAY_STATUS_UNPAY
			);
			$result = $this->Order->update($data, $where);
			if ($result) {
				$order = $this->Order->get_row(array('order_num' => $where['order_num']));
				$this->process($order);
			}
			$this->wxpay_notify->end(FALSE);
		}
	}

	public function alipay() {
		$request = $this->input->post();
		$ret = $this->alipay_sign($request);
		$ret = true;
		if ($ret && strtoupper($request['trade_status']) == 'TRADE_SUCCESS') {
			$this->load->model('api/Order_model', 'Order');
			$data = array(
				'pay_method' => REST_Controller::PAY_METHOD_ALIPY,
				'status' => REST_Controller::PAY_STATUS_PAYED,
				'pay_time' => time(),
				'ext_order_num' => $request['trade_no'],
				'sign_for_code' => rand(1000, 9999),
				'updated_at' => time()
			);
			$where = array(
				'order_num' => $request['out_trade_no'],
				'status' => REST_Controller::PAY_STATUS_UNPAY
			);
			$result = $this->Order->update($data, $where);
			if ($result) {
				$order = $this->Order->get_row(array('order_num' => $where['order_num']));
				$this->process($order);
			}
			echo 'success';
			die();
		}
	}

	public function alipay_refund() {
		$this->load->library('alipay');
		$result = $this->alipay->alipayNotify();
		if ($result) {
			set_time_limit(0);
			$batch_no = $this->post('batch_no');
			$result_details = $this->post('result_details');
			if(!empty($result_details)) {
				$tmp = explode('#', $result_details);
				$successArray = array();
				foreach ($tmp as $v) {
					$status = substr($v, strrpos($v, '^') + 1);
					if($status === 'SUCCESS') {
						$successArray[] = substr($v, 0, strpos($v, '^'));
					}
				}
				if(!empty($successArray)) {
					$this->load->model('backend/Order_model', 'Order');
					$rows = $this->Order->get_result(array('ext_order_num'=>$successArray,'status'=>  REST_Controller::PAY_STATUS_REFUNDING), array('select'=>'id,user_id'));
					$ids = $this->toSimpleArray($rows, 'id');
					$result = $this->Order->refund($ids, $batch_no);
					if($result) {
						$this->load->library('JPush');
						foreach ($rows as $v) {
							$this->jpush->push(array($v['user_id']), 'cfg_user_notify_refund', NULL, array('data' => $v['id']));
						}
						echo 'success';exit();
					}
				}
			}
			echo 'fail';exit();
		}	
	}

	private function process($order) {
		//记录日志
		$short_desc = sprintf($this->lang->line('s10003'), $order['sign_for_code']);
		$this->Order->log($order['id'], $order['status'], $short_desc, 3);
		//发送消息
		$this->load->library('JPush');
		$this->load->model('api/Agent_model', 'Agent');
		$rows = $this->Agent->getAgentAll($order['address_id']);
		$audience = $this->toSimpleArray($rows, 'id');
		$this->jpush->pushOrder($audience, 'cfg_agent_notify_new', $order, array('data' => $order['id']));
	}

	private function alipay_sign($request) {
		$needle = array('sign', 'sign_type', 'out_trade_no', 'trade_status', 'trade_no');
		if (empty($request) || count($request) < count($needle)) {
			return false;
		}
		foreach ($needle as $v) {
			if (!isset($request[$v]) || empty($request[$v])) {
				return false;
			}
		}
		$signString = base64_decode($request['sign']);
		$signType = $request['sign_type'];
		unset($request['sign']);
		unset($request['sign_type']);
		$keys = array_keys($request);
		sort($keys);
		$string = '';
		foreach ($keys as $v) {
			$string .= $v . '=' . $request[$v] . '&';
		}
		$string = trim($string, '&');
		switch (strtoupper($signType)) {
			case 'RSA':
				$pubKey = file_get_contents(realpath(APPPATH . 'third_party/alipay/qd65edb1535ei245/alipay_pubkey.pem'));
				/* 从PEM文件中提取私钥 */
				$res = openssl_get_publickey($pubKey);
				if ($res) {
					/* 对数据进行签名 */
					$result = openssl_verify($string, $signString, $res);
					/* 释放资源 */
					openssl_free_key($res);
					return $result == 1 ? true : false;
				}
				break;
			case 'MD5':
				break;
			default:break;
		}
		return false;
	}

	public function scheduled_task() {
		set_time_limit(0);
		$this->load->config('system_info');
		$this->load->model('api/Order_model', 'Order');
		$this->scheduled_unpay();
		$this->scheduled_signed();
		$this->scheduled_overtime();
	}

	private function scheduled_unpay() {
		$where = array(
			'status' => REST_Controller::PAY_STATUS_UNPAY,
			'created_at <' => time() - config_item('cfg_scheduled_close_o')
		);
		$result = $this->Order->get_result($where, array('select' => 'id'));
		if (!empty($result)) {
			$ids = $this->toSimpleArray($result, 'id');
			$this->Order->close($ids);
		}
	}

	private function scheduled_signed() {
		$data = array(
			'status' => REST_Controller::PAY_STATUS_FINISH,
			'updated_at' => time()
		);
		$where = array(
			'status' => REST_Controller::PAY_STATUS_SIGNED,
			'updated_at <' => time() - config_item('cfg_scheduled_finish_o')
		);
		$this->Order->update($data, $where);
	}

	private function scheduled_overtime() {
		$where = array(
			'status >' => REST_Controller::PAY_STATUS_UNPAY,
			'status <' => REST_Controller::PAY_STATUS_SIGNED,
			'pay_time <' => time() - config_item('cfg_scheduled_overtime_o'),
			'overtime' => REST_Controller::STATUS_DELETE
		);
		$result = $this->Order->get_result($where, array('select' => 'id,agent_id,user_id,status,contact_name,contact_address'));
		if (!empty($result)) {
			foreach ($result as $v) {
				$this->jpush->push(array($v['user_id']), 'cfg_user_notify_overtime', $v, array('data' => $v['id']));
				if ($v['status'] === REST_Controller::PAY_STATUS_SIGNED) {
					$label = 'cfg_agent_notify_overtime';
				} else {
					$label = 'cfg_agent_notify_overtime_n';
				}
				$this->jpush->push(array($v['agent_id']), $label, $v, array('data' => $v['id']));
				$data = array('overtime' => REST_Controller::STATUS_ACTIVE);
				$where = array('id' => $v['id']);
				$this->Order->update($data, $where);
			}
		}
	}

}
